/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.imagelinkfixer;

import cz.mzk.kramerius.commons.DatastreamId;
import cz.mzk.kramerius.commons.Dom4jUtils;
import cz.mzk.kramerius.commons.Namespaces;
import cz.mzk.kramerius.commons.PropertyLoader;
import cz.mzk.kramerius.fedoraaccess.FedoraConnector;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.XPath;

/**
 * Odstraní obrázkové datastreamy (předpoklad, že jsou ve Fedoře) a nahradí odkazy do image serveru
 * a dodá tiles-url. Vstupem je soubor obsahující názvy obrázků (v image serveru) ve stejném pořadí,
 * jako je pořadí stran.
 *
 * @author rehan
 */
public class AtlasFixer extends AbstractFixer {

    private static final int DELAY_MILLISECONDS = 100;//so that Fedora won't be overloaded
    private static final Logger logger = Logger.getLogger(KomenskyFixer.class.getName());
    private static XPath rdfDescription = Dom4jUtils.createXPath("//rdf:RDF/rdf:Description");
    private final String topLevelPid;
    private final String siglaTransformed;// 001/035/972 instead of 001035972
    private final String barcode;
    private final PageFilenameMapping mapping;

    public AtlasFixer(FedoraConnector conn, String topLevelPid, String sigla, String barcode, PageFilenameMapping mapping) {
        super(conn);
        this.topLevelPid = topLevelPid;
        this.siglaTransformed = transformSigla(sigla);
        this.barcode = barcode;
        this.mapping = mapping;
    }

    AtlasFixer(FedoraConnector conn, File linkfixerProperties, PageFilenameMapping mapping) throws IOException {
        super(conn);
        PropertyLoader loader = new PropertyLoader(linkfixerProperties);
        this.topLevelPid = loader.loadString("linkfixer.topLevelPid");

        this.siglaTransformed = transformSigla(loader.loadString("linkfixer.sigla"));
        this.barcode = loader.loadString("linkfixer.barcode");
        this.mapping = mapping;
    }

    public void run() throws InterruptedException {
        List<String> pagePids = getPidsOfPages(topLevelPid);
        logger.log(Level.INFO, "found {0} pages", pagePids.size());
        //System.err.println("sigla:" + siglaTransformed);
        int counter = 0;
        for (String pagePid : pagePids) {
            logger.log(Level.INFO, "fixing page {0}, {1}", new Object[]{counter, pagePid});
            String baseUrl = buildBaseUrl(counter);
            //System.err.println("baseUrl:" + baseUrl);
            String previewUrl = baseUrl + "/preview.jpg";
            //System.err.println("previewUrl:" + previewUrl);
            String fullUrl = baseUrl + "/big.jpg";
            //System.err.println("fulUrl:" + fullUrl);
            replaceDatastreamWithExternalUrl(pagePid, DatastreamId.IMG_PREVIEW, previewUrl, "náhled obrázku stránky");
            replaceDatastreamWithExternalUrl(pagePid, DatastreamId.IMG_THUMB, previewUrl, "náhled obrázku stránky");
            replaceDatastreamWithExternalUrl(pagePid, DatastreamId.IMG_FULL, fullUrl, "velký náhled obrázku stránky ke stažení nebo generovánḯ pdf");
            fixRelsExt(pagePid, baseUrl);
            Thread.sleep(DELAY_MILLISECONDS);
            counter++;
            //break;
        }
    }

    private String transformSigla(String sigla) {
        if (sigla.length() != 9) {
            throw new IllegalArgumentException("sigla '" + sigla + "' too short");
        }
        String result = sigla.substring(0, 3);
        result += "/";
        result += sigla.substring(3, 6);
        result += "/";
        result += sigla.substring(6, 9);
        return result;
    }

    private String buildBaseUrl(int counter) {
        StringBuilder result = new StringBuilder();
        result.append("http://imageserver.mzk.cz/mzk03/");
        result.append(siglaTransformed).append('/');
        result.append(barcode).append('/');
        String filename = mapping.getFilename(counter);
        result.append(filename.substring(0, filename.length() - ".jp2".length()));
        return result.toString();
    }

    private void replaceDatastreamWithExternalUrl(String pagePid, DatastreamId dsId, String url, String label) {
        String deletingText = "mazu datastream " + dsId + " objektu '" + pagePid + "', aby byl aktualizovan";
        logger.info(deletingText);
        conn.purgeDatastream(pagePid, dsId, deletingText);

        String insertingText = "vkládám nový datastream " + dsId + " (externally referenced) objektu '" + pagePid;
        logger.info(insertingText);
        conn.addExternallyReferencedDatastream(pagePid, dsId, url, "image/jpeg", label);
    }

    private void fixRelsExt(String pagePid, String baseUrl) {
        Document relsExt = conn.getXmlDatastreamDissemination(pagePid, DatastreamId.RELS_EXT);
        Document relsExtWithTiles = addTilesUrl(relsExt, baseUrl);
        String insertingText = "aktualizuji datastream " + DatastreamId.RELS_EXT + " objektu '" + pagePid;
        logger.info(insertingText);
        //conn.addGeneralRelation(pagePid, "tiless-url2", Namespaces.kramerius.getPrefix(), baseUrl);
        //conn.addRelationship(pagePid, "tiless-url", Namespaces.kramerius.getPrefix(), baseUrl);
        conn.updateDatastreamInlineContent(pagePid, DatastreamId.RELS_EXT, relsExtWithTiles);
    }

    private Document addTilesUrl(Document relsExt, String baseUrl) {
        Element descriptionEl = (Element) rdfDescription.selectSingleNode(relsExt);
        Element tilesUrlEl = descriptionEl.addElement(new QName("tiles-url", Namespaces.kramerius));
        tilesUrlEl.addText(baseUrl);
        return relsExt;
    }
}
